﻿using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Security;
using SHZY.Common.Enum;
using SHZY.Common.Extension;
using SHZY.Common.Filter;
using SHZY.Common.Models;
using SHZY.Common.Security;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Entitys.Permission;
using SHZY.Systems.Entitys.System;
using SHZY.Systems.Interfaces.System;
using SHZY.BaseData.Entitys.Dto.QmsBaseFactorystructure;
using SHZY.system.Entitys;
using SHZY.BaseData.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using SHZY.BaseData.Entitys;
using SHZY.BaseData.Entitys.Dto.QmsBaseInnspectionentry;
using Senparc.CO2NET.Extensions;
using NPOI.POIFS.Properties;
using SHZY.Systems.Entitys.Dto.DictionaryType;
using SHZY.BaseData.Entitys.Dto.Factory;
using SHZY.BaseData.Entitys.Entity;
using System.Linq;

namespace SHZY.BaseData;

/// <summary>
/// 业务实现：工厂建模.
/// </summary>
[ApiDescriptionSettings(Tag = "BaseData", Name = "QmsBaseFactorystructure", Order = 200)]
[Route("api/BaseData/[controller]")]
public class QmsBaseFactorystructureService : IQmsBaseFactorystructureService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<QmsBaseFactorystructureEntity> _repository;

    /// <summary>
    /// 服务基础仓储.-班组
    /// </summary>
    private readonly ISqlSugarRepository<QmsBaseFactorystructureEntity> _repository_children;

    /// <summary>
    /// 数据接口服务.
    /// </summary>
    private readonly IDataInterfaceService _dataInterfaceService;

    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager _userManager;

    private readonly ISqlSugarClient _db;

    /// <summary>
    /// 初始化一个<see cref="QmsBaseFactorystructureService"/>类型的新实例.
    /// </summary>
    public QmsBaseFactorystructureService(
        ISqlSugarRepository<QmsBaseFactorystructureEntity> qmsBaseFactorystructureRepository,
        IDataInterfaceService dataInterfaceService,
        ISqlSugarClient context,
        IUserManager userManager, ISqlSugarClient db)
    {
        _repository = qmsBaseFactorystructureRepository;
        _repository_children = qmsBaseFactorystructureRepository;
        _dataInterfaceService = dataInterfaceService;
        _userManager = userManager;
        _db = db;
    }

    /// <summary>
    /// 获取工厂建模.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {
        return (await _repository.FirstOrDefaultAsync(x => x.Id == id)).Adapt<QmsBaseFactorystructureInfoOutput>();
    }

    /// <summary>
    /// 获取工厂建模列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("")]
    public async Task<dynamic> GetList([FromQuery] QmsBaseFactorystructureListQueryInput input)
    {
        var queryable = _repository.Context.Queryable<QmsBaseFactorystructureEntity>()
            .WhereIF(!string.IsNullOrEmpty(input.fullName), it => it.FullName.Contains(input.fullName))
            .WhereIF(!string.IsNullOrEmpty(input.desc), it => it.Desc.Contains(input.desc))
            .WhereIF(!string.IsNullOrEmpty(input.type), it => it.Type.Equals(input.type))
            .Where(it => it.Type.Equals("Workshop") && (it.DeleteMark == null || it.DeleteMark == 0))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.FullName.Contains(input.keyword) || it.Desc.Contains(input.keyword) || it.Type.Contains(input.keyword))
             .Select(it => new QmsBaseFactorystructureListOutput
             {
                 id = it.Id,
                 parentId = it.ParentId,
                 enCode = it.EnCode,
                 fullName = it.FullName,
                 sortCode = it.SortCode,
                 desc = it.Desc,
                 type = SqlFunc.Subqueryable<DictionaryDataEntity>().Where(dic => dic.EnCode.Equals(it.Type) && dic.DictionaryTypeId.Equals("463856157161693189")).Select(dic => dic.FullName),
                 enabledMark = SqlFunc.IIF(it.EnabledMark == 0, "停用", "正常"),
             }).MergeTable();
        if (!string.IsNullOrEmpty(input.sidx))
        {
            queryable.OrderBy(input.sidx + " " + input.sort);
        }
        else
        {
            queryable.OrderBy("Encode" + " " + "desc");
        }
        var data = await queryable.ToPagedListAsync(input.currentPage, input.pageSize);//.OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort)
        foreach (var item in data.list)
        {
            var enCode = item.id;
            var sd = await _repository_children.Context.Queryable<QmsBaseFactorystructureEntity>().Where(w => w.ParentId == enCode).ToListAsync();
            item.children = await _repository_children.Context.Queryable<QmsBaseFactorystructureEntity>().Where(w => w.ParentId == enCode && (w.DeleteMark == null || w.DeleteMark == 0))
               .Select(it => new QmsBaseFactorystructureListOutput
               {
                   id = it.Id,
                   parentId = it.ParentId,
                   enCode = it.EnCode,
                   fullName = it.FullName,
                   sortCode = it.SortCode,
                   desc = it.Desc,
                   type = SqlFunc.Subqueryable<DictionaryDataEntity>().Where(dic => dic.EnCode.Equals(it.Type) && dic.DictionaryTypeId.Equals("463856157161693189")).Select(dic => dic.FullName),
                   enabledMark = SqlFunc.IIF(it.EnabledMark == 0, "停用", "正常"),
               }).ToListAsync();
            foreach (var item2 in item.children)
            {
                var enCode2 = item2.id;
                item2.children = await _repository_children.Context.Queryable<QmsBaseFactorystructureEntity>().Where(w => w.ParentId == enCode2 && (w.DeleteMark == null || w.DeleteMark == 0))
                   .Select(it => new QmsBaseFactorystructureListOutput
                   {
                       id = it.Id,
                       parentId = it.ParentId,
                       enCode = it.EnCode,
                       fullName = it.FullName,
                       sortCode = it.SortCode,
                       desc = it.Desc,
                       type = SqlFunc.Subqueryable<DictionaryDataEntity>().Where(dic => dic.EnCode.Equals(it.Type) && dic.DictionaryTypeId.Equals("463856157161693189")).Select(dic => dic.FullName),
                       enabledMark = SqlFunc.IIF(it.EnabledMark == 0, "停用", "正常"),
                   }).ToListAsync();
            }
        }
        return PageResult<QmsBaseFactorystructureListOutput>.SqlSugarPageResult(data);
    }

    /// <summary>
    /// 获取工厂建模列表.
    /// </summary>
    /// <param name="Type">请求参数.</param>
    /// <returns></returns>
    [HttpGet("GetListOption/{Type}")]
    public async Task<dynamic> GetListOption(string Type)
    {
        var data = new List<QmsBaseFactorystructureListOptionOutput>();
        if (Type == "Team" || Type == "Section")
        {
            data = await _repository.Context.Queryable<QmsBaseFactorystructureEntity>()
               .Where(it => it.Type.Equals("Workshop") && (it.DeleteMark == null || it.DeleteMark == 0))
               .OrderBy(it => it.Id)
               .Select(it => new QmsBaseFactorystructureListOptionOutput
               {
                   id = it.Id,
                   enCode = it.EnCode,
                   fullName = it.FullName,
                   parentId = it.ParentId,
                   hasChildren = true,
                   TreeNode = "1"
               }).ToListAsync();
        }

        if (Type == "Section")
        {
            foreach (var item in data)
            {
                var enCode = item.id;
                item.children = await _repository_children.Context.Queryable<QmsBaseFactorystructureEntity>().Where(w => w.ParentId == enCode && (w.DeleteMark == null || w.DeleteMark == 0))
                   .Select(it => new QmsBaseFactorystructureListOptionOutput
                   {
                       id = it.Id,
                       enCode = it.EnCode,
                       fullName = it.FullName,
                       parentId = it.ParentId,
                       hasChildren = true,
                       TreeNode = "2"
                   }).ToListAsync();

                //if (Type == "Section")
                //{
                //    foreach (var item2 in item.children)
                //    {
                //        var enCode2 = item2.enCode;
                //        item2.children = await _repository_children.Context.Queryable<QmsBaseFactorystructureEntity>().Where(w => w.ParentId == enCode2)
                //           .Select(it => new QmsBaseFactorystructureListOptionOutput
                //           {
                //               id = it.Id,
                //               enCode = it.EnCode,
                //               fullName = it.FullName,
                //               parentId = it.ParentId,
                //               hasChildren = true,
                //               TreeNode = "3"
                //           }).ToListAsync();
                //    }
                //}
            }
        }
        return data;
    }

    /// <summary>
    /// 新建工厂建模.
    /// </summary>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task Create([FromBody] QmsBaseFactorystructureCrInput input)
    {
        if (await _repository.AnyAsync(x => (x.EnCode == input.enCode) && x.DeleteMark == null))
            throw Oops.Oh(ErrorCode.COM1004);
        var entity = input.Adapt<QmsBaseFactorystructureEntity>();
        entity.Id = SnowflakeIdHelper.NextId();
        var isOk = await _repository.Context.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
    }

    /// <summary>
    /// 更新工厂建模.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("{id}")]
    public async Task Update(string id, [FromBody] QmsBaseFactorystructureUpInput input)
    {
        var entity = input.Adapt<QmsBaseFactorystructureEntity>();
        var isOk = await _repository.Context.Updateable(entity).UpdateColumns(it => new
        {
            it.ParentId,
            it.EnCode,
            it.FullName,
            it.SortCode,
            it.Desc,
            it.Type,
            it.EnabledMark,
            it.LastModifyTime,
            it.LastModifyUserId
        }).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
    }

    /// <summary>
    /// 删除工厂建模.
    /// </summary>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task Delete(string id)
    {
        //var isOk = await _repository.Context.Deleteable<QmsBaseFactorystructureEntity>().Where(it => it.Id.Equals(id)).ExecuteCommandAsync();
        //if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1002);
        var entity = await _repository.SingleAsync(x => x.Id == id && x.CreatorUserId == _userManager.UserId && x.DeleteMark == null);
        var isOk = await _repository.Context.Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
        if (!isOk)
            throw Oops.Oh(ErrorCode.COM1002);
    }

    /// <summary>
    /// 工厂建模信息下拉框（树形）.
    /// </summary>
    /// <returns></returns>
    [HttpGet("Selector/{id}")]
    public async Task<dynamic> GetSelector(string id)
    {
        var q1 = _repository.Context.Queryable<QmsBaseFactorystructureEntity>().Where(x => x.DeleteMark == null)
            .OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
            .Select(x => new QmsBaseFactorystructureSelectorOutput { id = x.Id, parentId = x.ParentId, enCode = x.EnCode, fullName = x.FullName, sortCode = x.SortCode, type = x.Type }).ToList();
        var q2 = _repository.Context.Queryable<QmsBaseStationEntity>().Where(x => x.DeleteMark == null)
            .OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
            .Select(x => new QmsBaseFactorystructureSelectorOutput { id = x.Id, parentId = x.ParentId, enCode = x.EnCode, fullName = x.FullName, sortCode = x.SortCode, type = "Station" }).ToList();
        var q1table = _db.Reportable(q1).ToQueryable();
        var q2table = _db.Reportable(q2).ToQueryable();
        var data = await _repository.Context.UnionAll(q1table, q2table).ToListAsync();

        if (!id.Equals("0"))
            data.RemoveAll(x => x.id == id);

        return new { list = data.ToTree("-1") };
    }
}